package com.frejoys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frejoys.common.config.ValueConfig;
import com.frejoys.common.constant.CommonConstant;
import com.frejoys.common.dto.admin.StoreIdAndOrderDto;
import com.frejoys.common.dto.admin.StoreIdAndPageDto;
import com.frejoys.common.dto.common.IdDto;
import com.frejoys.common.dto.common.OrderSnDto;
import com.frejoys.common.dto.order.*;
import com.frejoys.common.enums.*;
import com.frejoys.common.error.HttpStatus;
import com.frejoys.common.exception.GeneralException;
import com.frejoys.common.po.GoodsRepCountPo;
import com.frejoys.common.util.*;
import com.frejoys.common.vo.admin.OrderListVo;
import com.frejoys.common.vo.admin.UserVo;
import com.frejoys.common.vo.app.GoodsNameAndCoverVo;
import com.frejoys.common.vo.app.StoreIdAndOrderSnVo;
import com.frejoys.common.vo.order.*;
import com.frejoys.common.vo.pay.OrderSnWxJsPayVo;
import com.frejoys.common.vo.pay.WxJsPayVo;
import com.frejoys.common.vo.store.ScanOrderInfoVo;
import com.frejoys.common.vo.store.StoreActivityQueueVo;
import com.frejoys.common.vo.store.StoreActivityVo;
import com.frejoys.dao.entity.*;
import com.frejoys.dao.mapper.*;
import com.frejoys.service.*;
import com.frejoys.service.huajuan.HuajuanScoreService;
import lombok.RequiredArgsConstructor;
import org.aspectj.weaver.ast.Or;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * @author wangzhicheng
 * @version 1.0
 * @date 2024/4/16 11:54
 */
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    private final UserMapper userMapper;

    private final StoreUserMapper storeUserMapper;

    private final GoodsService goodsService;

    private final OrderGoodsService orderGoodsService;

    private final OrderAddressService orderAddressService;

    private final UserAddressMapper userAddressMapper;

    private final UserAddressService userAddressService;

    private final PayService payService;

    private final LoginService loginService;

    private final ValueConfig valueConfig;

    private final StoreActivityMapper storeActivityMapper;

    private final StoreMapper storeMapper;

    private final UserWalletLogService userWalletLogService;

    private final EventPublisherService eventPublisherService;

    private final StoreActivityQueueMapper storeActivityQueueMapper;

    private final ActivityMapper activityMapper;

    private final ActivityService activityService;

    private final RedissonClient redissonClient;

    private final OrderGoodsMapper orderGoodsMapper;

    private final GoodsMapper goodsMapper;

    private final UserService userService;

    private final StoreSaleMapper storeSaleMapper;

    private final StoreStatisticsDayMapper storeStatisticsDayMapper;
    
    private final StoreStatisticsYearMapper storeStatisticsYearMapper;

    private final HuajuanScoreService huajuanScoreService;

    private final UserWalletLogMapper userWalletLogMapper;


    @Override
    public boolean refundUpOrderPayStatus(Integer id, Integer newPayStatus, Integer oldPayStatus, Integer verify, Integer isScore) {
        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Order::getPayStatus, newPayStatus);
        wrapper.eq(Order::getId, id).eq(Order::getPayStatus, oldPayStatus).eq(Order::getVerify, verify).eq(Order::getIsScore, isScore);
        return update(wrapper);
    }

    @Override
    public boolean upVerifyStatus(Integer id, Integer newVerifyStatus, Integer oldVerifyStatus, Integer payStatus, Integer isScore) {
        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Order::getVerify, newVerifyStatus);
        wrapper.set(Order::getVerifyTime,TimeUtil.unixTime());
        wrapper.eq(Order::getId, id).eq(Order::getVerify, oldVerifyStatus).eq(Order::getPayStatus, payStatus).eq(Order::getIsScore, isScore);
        return update(wrapper);
    }

    @Override
    public boolean refundCallbackOrderPayStatus(Long orderSn, Integer oldPayStatus, Integer newPayStatus) {
        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Order::getPayStatus, newPayStatus);
        wrapper.eq(Order::getOrderSn, orderSn).eq(Order::getPayStatus, oldPayStatus);
        return update(wrapper);
    }

    @Override
    public boolean taskUpOrderPayStatus(List<Long> orderSn, Integer oldPayStatus, Integer newPayStatus, Integer verify) {
        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Order::getPayStatus, newPayStatus);
        wrapper.set(Order::getPayTime, TimeUtil.unixTime());

        if (verify != null) {
            wrapper.set(Order::getVerify, verify);
        }

        wrapper.in(Order::getOrderSn, orderSn).eq(Order::getPayStatus, oldPayStatus);
        return update(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderSnWxJsPayVo wxOrderConfirm(Long userId, OrderPlaceDto dto) {
        // 获取用户微信openid
        String openid = loginService.getUserOpenid(userId, ELoginType.wechat.getValue(),ESite.app.getValue());
        if (StrUtil.isEmpty(openid)) {
            throw new GeneralException(HttpStatus.wechatOpenIdNoExist);
        }

        // 创建订单
        Order order = createOrderInfo(userId, EPayType.wechat.getValue(), dto);

        AttachVo attachVo = new AttachVo();
        attachVo.setType(order.getType());

        WxJsPayVo jsPayVo = payService.wxJsPay(valueConfig.getAppUrl(), CommonConstant.description, openid, String.valueOf(order.getOrderSn()), CommonUtil.bigDecimalToFen(order.getPrice()), EPayCurrency.cny.getValue(), JSONUtil.toJsonStr(attachVo));

        OrderSnWxJsPayVo orderVo = new OrderSnWxJsPayVo();
        BeanUtil.copyProperties(jsPayVo, orderVo);
        orderVo.setOrderSn(order.getOrderSn());

        return orderVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderSnWxJsPayVo wxPayOrderConfirm(Long userId, PayMoneyDto dto) {
        // 获取用户微信openid
        String openid = loginService.getUserOpenid(userId, ELoginType.wechat.getValue(),ESite.app.getValue());
        if (StrUtil.isEmpty(openid)) {
            throw new GeneralException(HttpStatus.wechatOpenIdNoExist);
        }

        // 创建订单
        Order order = createOrderInfo(userId, EPayType.wechat.getValue(), dto);

        AttachVo attachVo = new AttachVo();
        attachVo.setType(order.getType());

        WxJsPayVo jsPayVo = payService.wxJsPay(valueConfig.getAppUrl(), CommonConstant.description, openid, String.valueOf(order.getOrderSn()), CommonUtil.bigDecimalToFen(order.getPrice()), EPayCurrency.cny.getValue(), JSONUtil.toJsonStr(attachVo));

        OrderSnWxJsPayVo orderVo = new OrderSnWxJsPayVo();
        BeanUtil.copyProperties(jsPayVo, orderVo);
        orderVo.setOrderSn(order.getOrderSn());

        return orderVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String aliOrderH5(Long userId, OrderPlaceDto dto) {
        // 创建订单
        Order order = createOrderInfo(userId, EPayType.alipay.getValue(), dto);

        AttachVo attachVo = new AttachVo();
        attachVo.setType(order.getType());

        return payService.aliH5Pay(valueConfig.getAppUrl(), CommonConstant.description, String.valueOf(order.getOrderSn()), CommonUtil.bigDecimalToString(order.getPrice()), JSONUtil.toJsonStr(attachVo));
    }

    @Override
    public String aliOrderPayH5(Long userId, PayMoneyDto dto) {
        // 创建订单
        Order order = createOrderInfo(userId, EPayType.alipay.getValue(), dto);

        AttachVo attachVo = new AttachVo();
        attachVo.setType(order.getType());

        return payService.aliH5Pay(valueConfig.getAppUrl(), CommonConstant.description, String.valueOf(order.getOrderSn()), CommonUtil.bigDecimalToString(order.getPrice()), JSONUtil.toJsonStr(attachVo));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Order createOrderInfo(Long userId, Integer payType, OrderPlaceDto dto) {
        // 购买的商品
        List<Integer> goodsId = dto.getGoodsInfo().stream().map(OrderGoodsDto::getGoodsId).toList();

        // 获取商品价格等信息
        List<Goods> goods = goodsService.getGoodsPriceRepCountInfo(dto.getStoreId(), goodsId);
        if (goods.isEmpty() || goods.size() != dto.getGoodsInfo().size()) {
            throw new GeneralException(HttpStatus.goodsNoExist);
        }

        // 订单编号
        long orderSn = SnowflakeUtil.appNextId();

        // 转换商品信息
        Map<Integer, Integer> goodsShopMap = dto.getGoodsInfo().stream().collect(Collectors.toMap(OrderGoodsDto::getGoodsId, OrderGoodsDto::getNum));

        // 计算支付金额
        BigDecimal payMoney = BigDecimal.ZERO;

        // 售出数量
        Integer soldCount = 0;

        // 订单商品
        List<OrderGoods> orderGoods = new ArrayList<>();

        // 订单库存商品
        List<GoodsRepCountPo> countPos = new ArrayList<>();

        // 处理
        for (Goods e : goods) {
            // 商品数量
            Integer num = goodsShopMap.get(e.getId());

            // 判断库存数量
            if (e.getRepCount() < num) {
                throw new GeneralException(HttpStatus.goodsCountNotEnough);
            }

            // 单价 * 数量
            BigDecimal priceTotal = CommonUtil.bigDecimalMultiply(e.getPrice(), CommonUtil.integerToBigDecimal(num));

            // 入库信息
            OrderGoods oGoods = new OrderGoods();
            oGoods.setOrderSn(orderSn);
            oGoods.setGoodsId(e.getId());
            oGoods.setNum(num);
            oGoods.setPrice(e.getPrice());
            oGoods.setPriceTotal(priceTotal);
            orderGoods.add(oGoods);

            // 库存信息
            GoodsRepCountPo po = new GoodsRepCountPo();
            po.setId(e.getId());
            // 减库存
            po.setRepCount(-num);
            countPos.add(po);

            // 总金额
            payMoney = payMoney.add(priceTotal);

            // 总数量
            soldCount += num;
        }

        // 地址

        if (dto.getUserAddressId() != null) {
            UserAddress userAddress = userAddressMapper.getInfoById(dto.getUserAddressId(), userId);
            // 保存订单收获地址
            OrderAddress orderAddress = new OrderAddress();
            BeanUtil.copyProperties(userAddress, orderAddress);
            orderAddress.setId(null);
            orderAddress.setOrderSn(orderSn);
            orderAddressService.addInfo(orderAddress);
        }

        Integer nt = TimeUtil.unixTime();

        // 创建订单
        Order order = new Order();
        order.setUserId(userId);
        order.setStoreId(dto.getStoreId());

        // 获取有效的店铺活动
        order.setStoreActivityId(storeActivityMapper.getValidActivityId(dto.getStoreId(), nt, EShelves.onSale.getValue(), EStatus.on.getValue()));
        order.setOrderSn(orderSn);
        order.setPrice(payMoney);
        // order.setRebateMoney(payMoney);
        order.setPayType(payType);
        order.setPayStatus(EPayStatus.wait.getValue());
        // 未支付时，支付时间用户判断订单超时时间，支付后变为支付时间
        order.setPayTime(nt + CommonConstant.orderTimeout);
        order.setReceive(EReceive.wait.getValue());
        order.setVerify(EVerify.wait.getValue());
        order.setIsScore(EIsScore.wait.getValue());
        order.setType(EOrderType.goodsOrder.getValue());
        order.setCreateTime(nt);
        order.setVerifyTime(nt);
        save(order);

        // 创建订单商品
        orderGoodsService.addInfo(orderGoods);

        // 增加店铺售出数量
        storeMapper.upSoldCount(dto.getStoreId(), soldCount);

        // 扣除商品数量
        try {
            goodsService.disposeGoodsRepCount(countPos);
        } catch (DataIntegrityViolationException e) {
            e.printStackTrace();
            throw new GeneralException(HttpStatus.goodsCountNotEnough);
        }

        // 放入订单超时集合
        CacheUtil.addOrderTimeoutSortSet(order.getOrderSn(), order.getPayTime());

        return order;
    }

    @Override
    public Order createOrderInfo(Long userId, Integer payType, PayMoneyDto dto) {

        // 订单编号
        long orderSn = SnowflakeUtil.appNextId();

        Integer nt = TimeUtil.unixTime();

        // 创建订单
        Order order = new Order();
        order.setUserId(userId);
        order.setStoreId(dto.getStoreId());

        // 获取有效的店铺活动
        order.setStoreActivityId(storeActivityMapper.getValidActivityId(dto.getStoreId(), nt, EShelves.onSale.getValue(), EStatus.on.getValue()));
        order.setOrderSn(orderSn);
        order.setPrice(dto.getPrice());
        // order.setRebateMoney(dto.getPrice());
        order.setPayType(payType);
        order.setPayStatus(EPayStatus.wait.getValue());
        // 未支付时，支付时间用户判断订单超时时间，支付后变为支付时间
        order.setPayTime(nt + CommonConstant.orderTimeout);
        order.setReceive(EReceive.wait.getValue());
        order.setVerify(EVerify.wait.getValue());
        order.setIsScore(EIsScore.wait.getValue());
        order.setType(dto.getType().equals(EStoreCodType.online.getValue()) ? EOrderType.virtuallyOnline.getValue() : EOrderType.virtuallyOffline.getValue());
        order.setCreateTime(nt);
        order.setVerifyTime(nt);
        save(order);

        return order;
    }

    @Override
    public boolean resetOrderRepCountPo(Long orderSn) {
        List<GoodsRepCountPo> countPos = new ArrayList<>();

        // 售出数量
        Integer soldCount = 0;

        // 获取订单商品
        List<OrderGoods> orderGoods = orderGoodsService.getGoodsListByOrderSn(orderSn);
        for (OrderGoods e : orderGoods) {
            // 库存信息
            GoodsRepCountPo po = new GoodsRepCountPo();
            po.setId(e.getGoodsId());
            // 加库存
            po.setRepCount(e.getNum());
            countPos.add(po);

            soldCount += e.getNum();
        }
        // 还原商品库存
        if (!countPos.isEmpty()) {
            goodsService.disposeGoodsRepCount(countPos);
        }

        // 增加店铺售出数量
        if (soldCount > 0) {
            // 获取店铺id
            Order order = baseMapper.getStoreIdByOrderSn(orderSn);
            if (order != null) {
                storeMapper.upSoldCount(order.getStoreId(), -soldCount);
            }
        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean orderRefund(Long userId, Integer id) {

        // 获取订单
        Order order = baseMapper.getForUpdateInfo(id);
        if (order == null) {
            throw new GeneralException(HttpStatus.orderNoExist);
        }

        if (!order.getUserId().equals(userId)) {
            throw new GeneralException(HttpStatus.orderInfoError);
        }

        checkOrder(order);

        // // 更新订单为退款中
        // if (!refundUpOrderPayStatus(id, EPayStatus.refunding.getValue(), EPayStatus.finish.getValue(), EVerify.wait.getValue(), EIsScore.wait.getValue())) {
        //     throw new GeneralException(HttpStatus.orderRefundError);
        // }

        // 更新订单为已退款
        if (!refundUpOrderPayStatus(id, EPayStatus.refund.getValue(), EPayStatus.finish.getValue(), EVerify.wait.getValue(), EIsScore.wait.getValue())) {
            throw new GeneralException(HttpStatus.orderRefundError);
        }

        // 订单库存商品还原
        if (order.getType().equals(EOrderType.goodsOrder.getValue())) {
            resetOrderRepCountPo(order.getOrderSn());
        }

        if (order.getPayType().equals(EPayType.wechat.getValue())) {
            return payService.wxRefund(valueConfig.getAppUrl(), String.valueOf(order.getOrderSn()), CommonUtil.bigDecimalToFen(order.getPrice()), EPayCurrency.cny.getValue());
        }

        return payService.aliRefund(String.valueOf(order.getOrderSn()), CommonUtil.bigDecimalToString(order.getPrice()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean orderScore(Long userId, Integer id) {
        Order order = baseMapper.getForUpdateInfo(id);
        if (order == null) {
            throw new GeneralException(HttpStatus.orderNoExist);
        }

        if (!order.getUserId().equals(userId)) {
            throw new GeneralException(HttpStatus.orderInfoError);
        }

        // 订单失效状态
        if (!order.getStatus().equals(EStatus.on.getValue())) {
            throw new GeneralException(HttpStatus.orderExpire);
        }

        // 未支付
        if (order.getPayStatus().equals(EPayStatus.wait.getValue())) {
            throw new GeneralException(HttpStatus.orderNoPay);
        }

        // 已退款
        if (order.getPayStatus().equals(EPayStatus.refund.getValue())) {
            throw new GeneralException(HttpStatus.orderRefund);
        }

        // 退款中
        if (order.getPayStatus().equals(EPayStatus.refunding.getValue())) {
            throw new GeneralException(HttpStatus.orderRefunding);
        }

        // 核销中
        if (order.getVerify().equals(EVerify.inProgress.getValue())) {
            throw new GeneralException(HttpStatus.orderVerifyError);
        }

        // 已返利
        if (order.getVerify().equals(EVerify.rebate.getValue())) {
            throw new GeneralException(HttpStatus.orderVerifyExistError);
        }

        // 判断是否已转积分
        if (order.getVerify().equals(EIsScore.finish.getValue())) {
            throw new GeneralException(HttpStatus.orderIsScore);
        }

        // 订单转积分
        if (!baseMapper.upScoreStatusAndRebateMoney(id, EIsScore.finish.getValue(), EIsScore.wait.getValue(), EPayStatus.finish.getValue(), EVerify.finish.getValue())) {
            throw new GeneralException(HttpStatus.orderToScoreError);
        }

        // 队列转积分
        // storeActivityQueueMapper.upQueueStatusAndRebateMoney(order.getOrderSn(), EStoreActivityQueueStatus.wait.getValue(), EStoreActivityQueueStatus.score.getValue(), order.getPrice().negate());
        storeActivityQueueMapper.upQueueStatusAndRebateMoney(order.getOrderSn(), EStoreActivityQueueStatus.wait.getValue(), EStoreActivityQueueStatus.score.getValue(), BigDecimal.ZERO);

        // if (!storeActivityQueueMapper.upQueueStatusAndRebateMoney(order.getOrderSn(), EStoreActivityQueueStatus.wait.getValue(), EStoreActivityQueueStatus.score.getValue(), order.getRebateMoney().negate())) {
        //     throw new GeneralException(HttpStatus.activityQueueError);
        // }

        // 同步花卷云积分
        huajuanScoreService.setUserScore(userId, CommonUtil.bigDecimalToInteger(order.getPrice()), EStatus.on.getValue());

        // 添加转换积分
        return userWalletLogService.addInfo(userId, order.getPrice(), SnowflakeUtil.appNextId(), EUserWalletLogType.toScore.getValue(), TimeUtil.unixTime(), EStatus.on.getValue());
    }

    @Override
    public boolean orderVerify(Long storeUserId, Integer id, Long orderSn) {
        Order order = baseMapper.getForUpdateInfo(id);
        if (order == null) {
            throw new GeneralException(HttpStatus.orderNoExist);
        }

        checkOrder(order);

        if (!order.getOrderSn().equals(orderSn)) {
            throw new GeneralException(HttpStatus.orderSnError);
        }

        // 获取商家拥有的店铺
        List<Integer> storeId = storeUserMapper.searchStoreIds(storeUserId);
        if (storeId.isEmpty()) {
            throw new GeneralException(HttpStatus.scanStoreNotFound);
        }

        if (!storeId.contains(order.getStoreId())) {
            throw new GeneralException(HttpStatus.scanStoreNotFound);
        }

        // 更新为核销中
        if (!upVerifyStatus(order.getId(), EVerify.inProgress.getValue(), EVerify.wait.getValue(), EPayStatus.finish.getValue(), EIsScore.wait.getValue())) {
            throw new GeneralException(HttpStatus.orderVerifyFail);
        }

        return true;
    }

    @Override
    public boolean notifyDisposeOrder(Long orderSn, Integer verify) {
        // 移除队列中订单
        CacheUtil.delOrderTimeoutSortSet(orderSn);

        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Order::getPayStatus, EPayStatus.finish.getValue());
        wrapper.set(Order::getPayTime, TimeUtil.unixTime());
        wrapper.set(Order::getStatus, EStatus.on.getValue());

        if (verify != null) {
            wrapper.set(Order::getVerify, verify);
        }

        wrapper.eq(Order::getOrderSn, orderSn).eq(Order::getPayStatus, EPayStatus.wait.getValue());
        return update(wrapper);
    }

    @Override
    public List<Order> getNoPayTimeoutOrder(Integer page, Integer size) {
        Page<Order> pageOrder = new Page<>(page, size);
        pageOrder.setSearchCount(false);

        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Order::getOrderSn, Order::getPayTime).lt(Order::getPayTime, TimeUtil.unixTime()).eq(Order::getStatus, EStatus.on.getValue()).eq(Order::getPayStatus, EPayStatus.wait.getValue());
        return baseMapper.selectPage(pageOrder, wrapper).getRecords();
    }

    @Override
    public List<Order> getVerifyInProgressOrder(Integer page, Integer size) {
        Page<Order> pageOrder = new Page<>(page, size);
        pageOrder.setSearchCount(false);

        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Order::getId).eq(Order::getVerify, EVerify.inProgress.getValue()).eq(Order::getStatus, EStatus.on.getValue()).eq(Order::getPayStatus, EPayStatus.finish.getValue());
        return baseMapper.selectPage(pageOrder, wrapper).getRecords();
    }

    @Override
    public List<Order> getListTaskByOrderSn(List<String> orderSn) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Order::getOrderSn, Order::getPayType, Order::getPayStatus, Order::getIsScore, Order::getVerify, Order::getType, Order::getStatus).in(Order::getOrderSn, orderSn);
        return list(wrapper);
    }

    @Override
    public boolean upOrderStatus(List<Long> orderSn, Integer status) {
        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Order::getStatus, status);
        wrapper.in(Order::getOrderSn, orderSn);
        return update(wrapper);
    }

    @Override
    public void checkOrder(Order order) {

        // 订单失效状态
        if (!order.getStatus().equals(EStatus.on.getValue())) {
            throw new GeneralException(HttpStatus.orderExpire);
        }

        // 未支付
        if (order.getPayStatus().equals(EPayStatus.wait.getValue())) {
            throw new GeneralException(HttpStatus.orderNoPay);
        }

        // 已退款
        if (order.getPayStatus().equals(EPayStatus.refund.getValue())) {
            throw new GeneralException(HttpStatus.orderRefund);
        }

        // 退款中
        if (order.getPayStatus().equals(EPayStatus.refunding.getValue())) {
            throw new GeneralException(HttpStatus.orderRefunding);
        }

        // 核销中
        if (order.getVerify().equals(EVerify.inProgress.getValue())) {
            throw new GeneralException(HttpStatus.orderVerifyError);
        }

        // 已结算
        if (order.getVerify().equals(EVerify.finish.getValue())) {
            throw new GeneralException(HttpStatus.orderVerifyError);
        }

        // 已返利
        if (order.getVerify().equals(EVerify.rebate.getValue())) {
            throw new GeneralException(HttpStatus.orderVerifyExistError);
        }

        // 判断是否已转积分
        if (order.getVerify().equals(EIsScore.finish.getValue())) {
            throw new GeneralException(HttpStatus.orderIsScore);
        }
    }

    @Override
    public ScanOrderInfoVo getStoreOrderInfoByOrderSn(Long orderSn, Long storeUserId) {

        // 获取订单
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Order::getId, Order::getStoreId, Order::getOrderSn, Order::getPrice, Order::getPayType, Order::getPayStatus, Order::getVerify, Order::getIsScore, Order::getStatus).eq(Order::getOrderSn, orderSn);
        Order order = getOnly(wrapper);
        if (order == null) {
            throw new GeneralException(HttpStatus.orderNoExist);
        }

        checkOrder(order);

        // 获取商家拥有的店铺
        List<Integer> storeId = storeUserMapper.searchStoreIds(storeUserId);
        if (storeId.isEmpty()) {
            throw new GeneralException(HttpStatus.scanStoreNotFound);
        }

        if (!storeId.contains(order.getStoreId())) {
            throw new GeneralException(HttpStatus.scanStoreNotFound);
        }

        // 获取店铺信息
        Store store = storeMapper.getSimpleInfo(order.getStoreId());
        if (store == null) {
            throw new GeneralException(HttpStatus.storeNotFound);
        }

        ScanOrderInfoVo vo = new ScanOrderInfoVo();
        vo.setOrderId(order.getId());
        vo.setStoreName(store.getName());
        vo.setLogo(AppConfigUtil.getUrlPrefix(store.getLogo(), EFileSize.logo.getValue()));
        vo.setCover(AppConfigUtil.getUrlPrefix(store.getCover()));
        vo.setPrice(order.getPrice());

        return vo;
    }

    @Override
    public Order getStoreIdPriceByOrderSn(Long orderSn) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Order::getStoreId, Order::getPrice).eq(Order::getOrderSn, orderSn);
        return getOnly(wrapper);
    }

    /**
     * 商家端分页查询订单数据
     *
     * @param dto
     * @param userId
     * @return
     */
//    @Override
//    public List<StoreOrderPageVo> pageOrder(OrderStorePageDto dto, Long userId) {
//        List<StoreOrderPageVo> orderList = new ArrayList<>();
//
//        Page<Order> page = new Page<>(dto.getPage(), dto.getSize());
//        page.setSearchCount(false);
//
//        //查询是否是店家
//        List<Integer> storeIds = storeUserMapper.searchStoreIds(userId);
//        if (CollectionUtils.isEmpty(storeIds)) {
//            //为空则代表不是店家
//            return orderList;
//        }
//
//        orderList = baseMapper.pageOrderList(page, dto, storeIds);
//        if (!orderList.isEmpty()) {
//
//            List<Integer> storeActivityIds = orderList.stream().map(StoreOrderPageVo::getStoreActivityId).toList();
//
//            List<StoreActivity> storeActivities = storeActivityMapper.getTypeByIds(storeActivityIds);
//
//            Map<Integer, Integer> map = storeActivities.stream().collect(Collectors.toMap(StoreActivity::getId, StoreActivity::getType));
//
//            List<Integer> types = storeActivities.stream().map(StoreActivity::getType).toList();
//
//            Map<Integer, String> activityMap = new HashMap<>();
//
//            if (!types.isEmpty()) {
//                LambdaQueryWrapper<Activity> wrapper = Wrappers.lambdaQuery();
//                wrapper.select(Activity::getType, Activity::getName).in(Activity::getType, types);
//                List<Activity> activities = activityMapper.selectList(wrapper);
//
//                if (CollectionUtil.isNotEmpty(activities)) {
//                    activityMap = activities.stream().collect(Collectors.toMap(Activity::getType, Activity::getName));
//                }
//            }
//
//
//            for (StoreOrderPageVo e : orderList) {
//                // 订单二维码，实物订单+已支付+没有订单二维码
//                if (e.getType().equals(EOrderType.goodsOrder.getValue()) && e.getPayStatus() > EPayStatus.wait.getValue() && StrUtil.isEmpty(e.getQrCode())) {
//                    eventPublisherService.sendOrderQrCodeService(e.getOrderSn());
//                }
//                if (!Objects.requireNonNull(activityMap).isEmpty()) {
//                    e.setActivityName(activityMap.get(map.get(e.getStoreActivityId())));
//                }
//                e.setQrCode(AppConfigUtil.getUrlPrefix(e.getQrCode(), EFileSize.qrcode.getValue()));
//                e.setLogo(AppConfigUtil.getUrlPrefix(e.getLogo(), EFileSize.logo.getValue()));
//                // e.setRebateMoney(CommonUtil.bigDecimalSubtract(e.getPrice(), e.getRebateMoney()));
//            }
//        }
//        return orderList;
//    }

//    /**
//     * 商家端查询订单详情
//     *
//     * @param idDto
//     */
//    @Override
//    public StoreOrderInfoVo getInfoByStore(IdDto idDto) {
//        StoreOrderInfoVo infoVo = new StoreOrderInfoVo();
//
//        //查询订单用户
//        LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery();
//        wrapper.select(Order::getUserId).eq(Order::getId, idDto.getId());
//        Order order = getOnly(wrapper);
//
//        if (ObjectUtil.isNotEmpty(order)) {
//
//            //获取非用户参数
//            UserOrderInfoVo info = getInfoByUser(idDto);
//
//            //封装数据
//            BeanUtils.copyProperties(info, infoVo);
//
//            LambdaQueryWrapper<User> userWrapper = Wrappers.lambdaQuery();
//            userWrapper.eq(User::getId, order.getUserId());
//
//            //查询用户
//            User user = userMapper.selectOne(userWrapper);
//
//            if (infoVo.getStoreActivityId() != null) {
//                //查询店铺活动
//                StoreActivity storeActivity = storeActivityMapper.selectById(infoVo.getStoreActivityId());
//                StoreActivityVo storeActivityVo = BeanUtil.copyProperties(storeActivity, StoreActivityVo.class);
//                storeActivityVo.setName(activityMapper.getNameByType(storeActivityVo.getType()));
//                infoVo.setActivityVo(storeActivityVo);
//            }
//
//            if (ObjectUtil.isNotEmpty(user)) {
//                infoVo.setUserVo(BeanUtil.copyProperties(user, UserVo.class));
//            }
//        }
//
//
//        return infoVo;
//    }

    /**
     * 用户查询订单数据
     */
    @Override
    public List<UserOrderPageVo> pageOrderList(OrderUserPageDto dto, Long userId) {

        List<UserOrderPageVo> orderList = new ArrayList<>();

        Page<Order> page = new Page<>(dto.getPage(), dto.getSize());
        page.setSearchCount(false);

        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Order::getId, Order::getUserId, Order::getStoreId, Order::getStoreActivityId,
                        Order::getPrice, Order::getPayType, Order::getPayStatus, Order::getPayTime,
                        Order::getReceive, Order::getVerify, Order::getIsScore, Order::getOrderSn,
                        Order::getQrCode, Order::getType, Order::getCreateTime)
                .eq(Order::getUserId, userId).eq(Order::getStatus, EStatus.on.getValue())
                .orderByDesc(Order::getCreateTime);

        if (dto.getType() != null) {
            //查询待支付
            if (dto.getType() == EOrderListType.awaitPayStatus.getValue()){
                wrapper.eq(Order::getPayStatus,EPayStatus.wait.getValue());
            }
            //查询待返利 已支付+待收货+不等于已返利+待转积分
            if (dto.getType() == EOrderListType.awaitReceive.getValue()){
                wrapper.eq(Order::getPayStatus,EPayStatus.finish.getValue());
                wrapper.eq(Order::getReceive,EReceive.wait.getValue());
                wrapper.ne(Order::getVerify,EVerify.rebate.getValue());
                wrapper.eq(Order::getIsScore,EIsScore.wait.getValue());
            }
            //查询待核销 已支付+待核销+待转积分
            if (dto.getType() == EOrderListType.awaitVerify.getValue()){
                wrapper.eq(Order::getPayStatus,EPayStatus.finish.getValue());
                wrapper.eq(Order::getVerify,EVerify.wait.getValue());
                wrapper.eq(Order::getIsScore,EIsScore.wait.getValue());
            }
            //查询已返利
            if (dto.getType() == EOrderListType.alreadyIsScore.getValue()){
                wrapper.eq(Order::getVerify,EVerify.rebate.getValue());
            }
        }

        if (dto.getStartTime() != null) {
            wrapper.ge(Order::getCreateTime, dto.getStartTime());
        }

        if (dto.getEndTime() != null) {
            wrapper.le(Order::getCreateTime, dto.getEndTime());
        }
        //根据店铺名查询订单
        if (StrUtil.isNotEmpty(dto.getStoreName())){
            List<Store> storeList = storeMapper.getStoreNameById((dto.getStoreName()));
            if (storeList.isEmpty()){
                return new ArrayList<>();
            }
            List<Integer> storeIds = storeList.stream().map(Store::getId).toList();
            wrapper.in(Order::getStoreId,storeIds);

        }

        List<Order> list = baseMapper.selectPage(page, wrapper).getRecords();

        if (!list.isEmpty()) {
            //筛选订单里所有的店铺并查询
            List<Integer> storeIds = list.stream().map(Order::getStoreId).toList();
            List<Store> storeList = storeMapper.getStoreList(storeIds);

            List<Integer> activityIds = list.stream().map(Order::getStoreActivityId).toList();

            Map<Integer, String> activityMap = activityService.getTypeNameMap();

            Map<Integer, StoreActivity> saMap = new HashMap<>();

            if (!activityIds.isEmpty()) {
                List<StoreActivity> storeActivities = storeActivityMapper.getTypeByIds(activityIds);

                saMap = storeActivities.stream().collect(Collectors.toMap(StoreActivity::getId, storeActivity -> storeActivity));

            }

            //得到店铺id和名称的map
            Map<Integer, Store> storeMap = storeList.stream().collect(Collectors.toMap(Store::getId, store -> store));

            List<Long> orderSns = list.stream().map(Order::getOrderSn).toList();

            //查询商品信息
            LambdaQueryWrapper<OrderGoods> orderGoodsWrapper = new LambdaQueryWrapper<>();
            orderGoodsWrapper.select(OrderGoods::getOrderSn,OrderGoods::getGoodsId,OrderGoods::getNum,OrderGoods::getPriceTotal)
                    .in(OrderGoods::getOrderSn,orderSns);
            List<OrderGoods> orderGoods = orderGoodsMapper.selectList(orderGoodsWrapper);

            Map<Integer, GoodsNameAndCoverVo> goodsMap = new HashMap<>();
            Map<Long, List<OrderGoods>> orderGoodsMap = new HashMap<>();
            if (!orderGoods.isEmpty()){
                List<Integer> goodsIds = orderGoods.stream().map(OrderGoods::getGoodsId).toList();
                orderGoodsMap = orderGoods.stream().collect(Collectors.groupingBy(OrderGoods::getOrderSn));

                LambdaQueryWrapper<Goods> goodsWrapper = new LambdaQueryWrapper<>();
                goodsWrapper.select(Goods::getId,Goods::getName,Goods::getCover)
                                .in(Goods::getId,goodsIds);
                List<Goods> goodsList = goodsMapper.selectList(goodsWrapper);
                List<GoodsNameAndCoverVo> goodsNameAndCoverVos = BeanUtil.copyToList(goodsList, GoodsNameAndCoverVo.class);
                goodsMap = goodsNameAndCoverVos.stream().collect(Collectors.toMap(GoodsNameAndCoverVo::getId, goodsNameAndCoverVo -> goodsNameAndCoverVo));
            }

            //获取排队位置
            LambdaQueryWrapper<StoreActivityQueue> aWrapper = new LambdaQueryWrapper<>();
            aWrapper.select(StoreActivityQueue::getStoreActivityId,StoreActivityQueue::getOrderSn)
                    .in(StoreActivityQueue::getStoreActivityId,activityIds)
                    .eq(StoreActivityQueue::getStatus, EStoreActivityQueueStatus.wait.getValue())
                    .orderByAsc(StoreActivityQueue::getCreateTime);
            List<StoreActivityQueue> storeActivityQueues = storeActivityQueueMapper.selectList(aWrapper);
            Map<Integer, List<StoreActivityQueue>> storeActivityQueueMap = storeActivityQueues.stream().collect(Collectors.groupingBy(StoreActivityQueue::getStoreActivityId));

            for (Order e : list) {

                UserOrderPageVo vo = new UserOrderPageVo();
                //插入店铺信息
                BeanUtils.copyProperties(e, vo);
                if (storeMap.containsKey(vo.getStoreId())) {
                    vo.setStoreName(storeMap.get(vo.getStoreId()).getName());
                    vo.setStoreType(storeMap.get(vo.getStoreId()).getType());
                    vo.setLogo(AppConfigUtil.getUrlPrefix(storeMap.get(vo.getStoreId()).getLogo(), EFileSize.logo.getValue()));
                }
                vo.setQrCode(AppConfigUtil.getUrlPrefix(e.getQrCode(), EFileSize.qrcode.getValue()));

                // 订单二维码，实物订单+已支付+没有订单二维码
                if (e.getType().equals(EOrderType.goodsOrder.getValue()) && e.getPayStatus() > EPayStatus.wait.getValue() && StrUtil.isEmpty(e.getQrCode())) {
                    eventPublisherService.sendOrderQrCodeService(e.getOrderSn());
                }

                //插入排队信息
                Integer nowSort = 0;
                if (e.getVerify() != EVerify.rebate.getValue()){
                    if (storeActivityQueueMap.containsKey(e.getStoreActivityId())){
                        List<StoreActivityQueue> activityQueues = storeActivityQueueMap.get(e.getStoreActivityId());
                        List<Long> idList = activityQueues.stream().map(StoreActivityQueue::getOrderSn).toList();

                        if (idList.contains(e.getOrderSn())) {
                            nowSort = idList.indexOf(e.getOrderSn())+1;
                        }
                    }
                }

                vo.setNowSort(nowSort);

                //插入活动名称
                StoreActivity storeActivity = saMap.get(e.getStoreActivityId());
                if (ObjectUtil.isNotEmpty(storeActivity)) {
                    vo.setActivityName(activityMap.get(storeActivity.getType()));

                    //排队第一位的时候显示活动当前金额
                    if (vo.getNowSort() == 1){
                        vo.setMoney(storeActivity.getMoney());
                    }
                }

                List<GoodsNameAndCoverVo> goodsListVos = new ArrayList<>();

                //插入商品数量
                Integer goodsNum = 0;
                if (orderGoodsMap.containsKey(e.getOrderSn())){
                    List<OrderGoods> orderGoodsList = orderGoodsMap.get(e.getOrderSn());
                    for (OrderGoods s : orderGoodsList){
                        goodsNum += s.getNum();

                        //插入商品信息
                        GoodsNameAndCoverVo goodsNameAndCoverVo = goodsMap.get(s.getGoodsId());
                        if (ObjectUtil.isNotEmpty(goodsNameAndCoverVo)){
                            goodsNameAndCoverVo.setCover(CommonUtil.getFirstCover(goodsNameAndCoverVo.getCover()));
                            goodsListVos.add(goodsNameAndCoverVo);
                        }
                    }
                    //没有商品 把店铺信息插入到商品信息中-卢
                }else if (!orderGoodsMap.containsKey(e.getOrderSn()) && storeMap.containsKey(vo.getStoreId())){
                    GoodsNameAndCoverVo goodsNameAndCoverVo = new GoodsNameAndCoverVo();
                    goodsNameAndCoverVo.setName(storeMap.get(vo.getStoreId()).getName());
                    goodsNameAndCoverVo.setCover(AppConfigUtil.getUrlPrefix(storeMap.get(vo.getStoreId()).getLogo()));
                    goodsListVos.add(goodsNameAndCoverVo);
                }
                vo.setGoodsNum(goodsNum);
                vo.setGoodsListVos(goodsListVos);
                orderList.add(vo);
            }

        }

        return orderList;
    }


    /**
     * 用户查询订单详情
     *
     * @param idDto 订单id
     */
    @Override
    public UserOrderInfoVo getInfoByUser(IdDto idDto) {
        UserOrderInfoVo infoVo = new UserOrderInfoVo();
        //查询出订单信息
        Order order = getOnly(Wrappers.<Order>lambdaQuery().eq(Order::getId, idDto.getId()));
        if (ObjectUtil.isNotEmpty(order)) {
            BeanUtil.copyProperties(order, infoVo);
            Store store = storeMapper.getNameInfo(infoVo.getStoreId());

            if (ObjectUtil.isNotEmpty(store)){
                infoVo.setStoreName(store.getName());
                infoVo.setLogo(AppConfigUtil.getUrlPrefix(store.getLogo(),EFileSize.logo.getValue()));
            }
            //查出订单商品信息
            List<OrderGoodsVo> goodsListDetailByOrderSn = orderGoodsService.getGoodsListDetailByOrderSn(infoVo.getOrderSn());
            //没有商品把店铺信息设置进去 前端需要展示
            if (goodsListDetailByOrderSn.isEmpty() && ObjectUtil.isNotEmpty(store)){
                OrderGoodsVo vo = new OrderGoodsVo();
                vo.setCover(AppConfigUtil.getUrlPrefix(store.getLogo(),EFileSize.logo.getValue()));
                vo.setGoodsName(store.getName());
                vo.setNum(1);
                vo.setPrice(order.getPrice());
                goodsListDetailByOrderSn.add(vo);
            }
            infoVo.setGoodsVos(goodsListDetailByOrderSn);

            //查出订单地址
            LambdaQueryWrapper<OrderAddress> wrapper = Wrappers.lambdaQuery();
            wrapper.select(OrderAddress::getName, OrderAddress::getPhone, OrderAddress::getProvince, OrderAddress::getCity,
                    OrderAddress::getDistrict, OrderAddress::getStreet, OrderAddress::getAddress).eq(OrderAddress::getOrderSn, infoVo.getOrderSn());

            OrderAddress orderAddress = orderAddressService.getOnly(wrapper);
            OrderAddressVo addressVo = new OrderAddressVo();
            if (ObjectUtil.isNotEmpty(orderAddress)) {
                BeanUtils.copyProperties(orderAddress, addressVo);

            }
//            else {
//                //没有地址信息 插入用户电话
//                User user = userService.getInfo(order.getUserId());
//                    if (ObjectUtil.isNotEmpty(user)){
//                        addressVo.setPhone(user.getPhone());
//                    }
//                }
            StoreActivityQueueVo activity = storeActivityQueueMapper.getActivity(order.getUserId(), infoVo.getOrderSn(), order.getStoreActivityId());
            if(ObjectUtil.isNotEmpty(activity)) {
                activity.setName(activityMapper.getNameByType(activity.getType()));
            }
            // 订单二维码，实物订单+已支付+没有订单二维码
            if (order.getType().equals(EOrderType.goodsOrder.getValue()) && order.getPayStatus() > EPayStatus.wait.getValue() && StrUtil.isEmpty(order.getQrCode())) {
                eventPublisherService.sendOrderQrCodeService(order.getOrderSn());
            }
            infoVo.setQrCode(AppConfigUtil.getUrlPrefix(order.getQrCode(), EFileSize.qrcode.getValue()));
            infoVo.setQueueVo(activity);
            infoVo.setAddressVo(addressVo);
        }
        return infoVo;
    }


    @Override
    public StoreIdAndOrderSnVo getPayStatus(OrderSnDto dto) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Order::getPayStatus,Order::getStoreId)
                .eq(Order::getOrderSn,dto.getOrderSn());
        Order order = getOnly(wrapper);

        StoreIdAndOrderSnVo vo = new StoreIdAndOrderSnVo();

        if (order != null){
            vo.setStoreId(order.getStoreId());
            vo.setPayStatus(order.getPayStatus());
        }
        return vo;
    }

    
    @Override
    public IPage<OrderListVo> orderListInfo(StoreIdAndOrderDto dto) {
        Page page = new Page<>(dto.getPage(), dto.getSize());
        
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        if (dto.getUserId() != null){
            wrapper.eq(Order::getUserId,dto.getUserId());
        }
        if (dto.getOrderSn() != null){
            wrapper.eq(Order::getOrderSn,dto.getOrderSn());
        }
        if (dto.getStoreId() != null){
            wrapper.eq(Order::getStoreId,dto.getStoreId());
        }
        if (!dto.getVerify().isEmpty()){
            wrapper.in(Order::getVerify,dto.getVerify());
        }
        if (!dto.getPayStatus().isEmpty()){
            wrapper.in(Order::getPayStatus,dto.getPayStatus());
        }
        if (!dto.getReceive().isEmpty()){
            wrapper.in(Order::getReceive,dto.getReceive());
        }
        if (!dto.getIsScore().isEmpty()){
            wrapper.in(Order::getIsScore,dto.getIsScore());
        }
        if (!dto.getType().isEmpty()){
            wrapper.in(Order::getType,dto.getType());
        }
        if (dto.getStatus() != null){
            wrapper.eq(Order::getStatus,dto.getStatus());
        }
        if (StrUtil.isNotEmpty(dto.getPhone())){
            Long userId = userMapper.phoneByUserId(dto.getPhone());
            if (userId == null){
                return new Page<>();
            }
            wrapper.eq(Order::getUserId,userId);
        }
        if (StrUtil.isNotEmpty(dto.getStoreName())){
            List<Store> stores = storeMapper.getStoreNameById(dto.getStoreName());
            if (stores.isEmpty()){
                return new Page<>();
            }
            List<Integer> ids = stores.stream().map(Store::getId).toList();
            wrapper.in(Order::getStoreId,ids);
        }
        wrapper.orderByDesc(Order::getCreateTime);
        Page<Order> orderPage = baseMapper.selectPage(page, wrapper);
        IPage<OrderListVo> orderListVoIPage = orderPage.convert(order -> BeanUtil.copyProperties(order, OrderListVo.class));
        List<OrderListVo> orderListVos = orderListVoIPage.getRecords();
        
        if (!orderListVos.isEmpty()){
            List<Long> userIds = orderListVos.stream().map(OrderListVo::getUserId).distinct().toList();
            List<Integer> storeIds = orderListVos.stream().map(OrderListVo::getStoreId).distinct().toList();

            //查询用户信息
            List<User> users = userMapper.getUserByIds(userIds);
            Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user));

            //查询店铺信息
            LambdaQueryWrapper<Store> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(Store::getId,Store::getName,Store::getLogo)
                    .in(Store::getId,storeIds);
            List<Store> storeList = storeMapper.selectList(queryWrapper);
            Map<Integer, Store> storeMap = storeList.stream().collect(Collectors.toMap(Store::getId, store -> store));

            orderListVos.forEach(vo -> {
                if (userMap.containsKey(vo.getUserId())){
                    User user = userMap.get(vo.getUserId());
                    vo.setNickname(user.getNickname());
                    vo.setPhone(user.getPhone());
                }
                if (storeMap.containsKey(vo.getStoreId())){
                    Store store = storeMap.get(vo.getStoreId());
                    vo.setStoreName(store.getName());
                    vo.setLogo(AppConfigUtil.getUrlPrefix(store.getLogo(),EFileSize.logo.getValue()));
                }
            });
        }
        return orderListVoIPage;
    }



    @Override
    public OrderAndGoodsListVo storeOrderListInfo(OrderListDto dto,Long userId) {
        Page page = new Page<>(dto.getPage(), dto.getSize());
//        page.setSearchCount(false);

        OrderAndGoodsListVo vo = new OrderAndGoodsListVo();
        if (dto.getStoreId() == null){
            return vo;
        }
        //校验是否能够查看店铺订单列表信息
        Integer id = storeUserMapper.getStoreUserId( userId,dto.getStoreId());
        if (id == null){
            throw new GeneralException(HttpStatus.routeRuleNone);
        }

        Integer startTime = 0;
        Integer endTime = 0;

        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getStoreId,dto.getStoreId())
                .eq(Order::getStatus, EStatus.on.getValue())
                .orderByDesc(Order::getCreateTime);
        //订单状态赛选
        if (dto.getType() != null) {
            //查询待返利 已支付+待收货+不等于已返利+待转积分
            if (dto.getType() == EOrderListType.awaitReceive.getValue()){
                wrapper.eq(Order::getPayStatus,EPayStatus.finish.getValue());
                wrapper.eq(Order::getReceive,EReceive.wait.getValue());
                wrapper.ne(Order::getVerify,EVerify.rebate.getValue());
                wrapper.eq(Order::getIsScore,EIsScore.wait.getValue());
            }
            //查询待核销 已支付+待核销+待转积分
            if (dto.getType() == EOrderListType.awaitVerify.getValue()){
                wrapper.eq(Order::getPayStatus,EPayStatus.finish.getValue());
                wrapper.eq(Order::getVerify,EVerify.wait.getValue());
                wrapper.eq(Order::getIsScore,EIsScore.wait.getValue());
            }
            //查询已返利
            if (dto.getType() == EOrderListType.alreadyIsScore.getValue()){
                wrapper.eq(Order::getVerify,EVerify.rebate.getValue());
            }
        }
        //时间筛选
        if (StrUtil.isNotEmpty(dto.getStartTime()) && StrUtil.isNotEmpty(dto.getEndTime())){
            //当天开始时间
            startTime = TimeUtil.beginOfDay(TimeUtil.unixTime(dto.getStartTime()));
            //当天结束时间
            endTime = TimeUtil.endOfDay(TimeUtil.unixTime(dto.getEndTime()));

            Long day = TimeUtil.diffDay(startTime, endTime);

            //只能赛选三个月的订单
            if (day > 90){
                throw new GeneralException(HttpStatus.filtrationOutOfRangeError);
            }

            if (dto.getTimeStatus() == ETimeStatus.orderTime.getValue()){
                wrapper.ge(Order::getCreateTime,startTime);
                wrapper.le(Order::getCreateTime,endTime);
            }else if (dto.getTimeStatus() == ETimeStatus.payTime.getValue()){
                wrapper.ge(Order::getPayTime,startTime);
                wrapper.le(Order::getPayTime,endTime);
            }else if (dto.getTimeStatus() == ETimeStatus.verifyTime.getValue()){
                wrapper.ge(Order::getVerifyTime,startTime);
                wrapper.le(Order::getVerifyTime,endTime);
            }
        }
        IPage<Order> orderList = baseMapper.selectPage(page, wrapper);
        IPage<StoreOrderListVo> storeOrderListVoIPage = orderList.convert(order -> BeanUtil.copyProperties(order, StoreOrderListVo.class));
        List<StoreOrderListVo> vos = storeOrderListVoIPage.getRecords();

        if (!vos.isEmpty()){
            //订单编号
            List<Long> orderSns = vos.stream().map(StoreOrderListVo::getOrderSn).toList();

            //用户id
            List<Long> userIds = vos.stream().map(StoreOrderListVo::getUserId).distinct().toList();

            //订单id
            List<Integer> orderIds = vos.stream().map(StoreOrderListVo::getId).toList();

            //活动id
            List<Integer> storeActivityIds = vos.stream().map(StoreOrderListVo::getStoreActivityId).distinct().toList();

            //查询商品信息
            Map<Long,List<GoodsNameAndCoverVo>> goodsMap = orderGoodsService.goodsListByOrderSns(orderSns);

            //查询店铺简单信息
            Store store = storeMapper.getSimpleInfo(dto.getStoreId());

            //查询下单用户信息
            List<User> users = userMapper.getUserByIds(userIds);
            Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, user -> user));

            //查询订单商家实收
            LambdaQueryWrapper<StoreSale> storeSaleWrapper = new LambdaQueryWrapper<>();
            storeSaleWrapper.select(StoreSale::getMoney,StoreSale::getOrderId)
                    .eq(StoreSale::getStoreId,dto.getStoreId())
                    .in(StoreSale::getOrderId,orderIds);
            List<StoreSale> storeSales = storeSaleMapper.selectList(storeSaleWrapper);
            Map<Integer, BigDecimal> storeMoenyMap = storeSales.stream().collect(Collectors.toMap(StoreSale::getOrderId, StoreSale::getMoney));


            //获取排队位置
            LambdaQueryWrapper<StoreActivityQueue> aWrapper = new LambdaQueryWrapper<>();
            aWrapper.select(StoreActivityQueue::getStoreActivityId,StoreActivityQueue::getOrderSn)
                    .in(StoreActivityQueue::getStoreActivityId,storeActivityIds)
                    .eq(StoreActivityQueue::getStatus, EStoreActivityQueueStatus.wait.getValue())
                    .orderByAsc(StoreActivityQueue::getCreateTime);
            List<StoreActivityQueue> storeActivityQueues = storeActivityQueueMapper.selectList(aWrapper);
            Map<Integer, List<StoreActivityQueue>> storeActivityQueueMap = storeActivityQueues.stream().collect(Collectors.groupingBy(StoreActivityQueue::getStoreActivityId));

            for (StoreOrderListVo storeOrderListVo:vos) {

                if (StrUtil.isNotEmpty(storeOrderListVo.getQrCode())){
                    storeOrderListVo.setQrCode(AppConfigUtil.getUrlPrefix(storeOrderListVo.getQrCode() , EFileSize.qrcode.getValue()));
                }

                //插入商品信息
                if (goodsMap.containsKey(storeOrderListVo.getOrderSn())){
                    storeOrderListVo.setGoodsNameAndCoverVos(goodsMap.get(storeOrderListVo.getOrderSn()));
                }else {
                    //没有商品插入店铺信息
                    List<GoodsNameAndCoverVo> voList = new ArrayList<>();
                    GoodsNameAndCoverVo goodsVo = new GoodsNameAndCoverVo();
                    goodsVo.setCover(AppConfigUtil.getUrlPrefix(store.getLogo()));
                    goodsVo.setName(store.getName());
                    voList.add(goodsVo);
                    storeOrderListVo.setGoodsNameAndCoverVos(voList);
                }

                //插入用户信息
                if (userMap.containsKey(storeOrderListVo.getUserId())){
                    storeOrderListVo.setNickname(userMap.get(storeOrderListVo.getUserId()).getNickname());
                }

                //插入商家实际收款
                if (storeMoenyMap.containsKey(storeOrderListVo.getId())){
                    storeOrderListVo.setStoreMoney(storeMoenyMap.get(storeOrderListVo.getId()));
                }

                //插入当前排队位置
                Integer nowSort = 0;
                if (storeOrderListVo.getVerify() != EVerify.rebate.getValue() || storeOrderListVo.getIsScore() == EIsScore.wait.getValue()){
                    if (storeActivityQueueMap.containsKey(storeOrderListVo.getStoreActivityId())){
                        List<StoreActivityQueue> activityQueues = storeActivityQueueMap.get(storeOrderListVo.getStoreActivityId());
                        List<Long> idList = activityQueues.stream().map(StoreActivityQueue::getOrderSn).toList();

                        if (idList.contains(storeOrderListVo.getOrderSn())) {
                            nowSort = idList.indexOf(storeOrderListVo.getOrderSn())+1;
                        }
                    }
                }
                storeOrderListVo.setNowSort(nowSort);
                //插入店铺信息
                storeOrderListVo.setStoreName(store.getName());
                storeOrderListVo.setLogoUrl(AppConfigUtil.getUrlPrefix(store.getLogo(),EFileSize.logo.getValue()));

            }
            vo.setStoreOrderListVos(vos);
        }

        //查询店铺总收益
        BigDecimal storeMoneyAll = BigDecimal.ZERO;
        List<BigDecimal> moneyList = new ArrayList<>();
        //时间赛选查日统计 未赛选查年统计
        //待返利 待核销 已返利 不显示店家实际收款总额
        if (dto.getType() == null){
            if (StrUtil.isNotEmpty(dto.getStartTime()) && StrUtil.isNotEmpty(dto.getEndTime())){
                Integer sTime = Integer.valueOf(TimeUtil.formatYMD(startTime));
                Integer eTime = Integer.valueOf(TimeUtil.formatYMD(endTime));

                LambdaQueryWrapper<StoreStatisticsDay> yearWrapper = new LambdaQueryWrapper<>();
                yearWrapper.select(StoreStatisticsDay::getMoney);
                yearWrapper.eq(StoreStatisticsDay::getStoreId,dto.getStoreId());
                yearWrapper.ge(StoreStatisticsDay::getYmd,sTime);
                yearWrapper.le(StoreStatisticsDay::getYmd,eTime);
                List<StoreStatisticsDay> statisticsDays = storeStatisticsDayMapper.selectList(yearWrapper);
                moneyList = statisticsDays.stream().map(StoreStatisticsDay::getMoney).toList();
            }else {
                //默认查询全部
                LambdaQueryWrapper<StoreStatisticsYear> yearWrapper = new LambdaQueryWrapper<>();
                yearWrapper.select(StoreStatisticsYear::getMoney);
                yearWrapper.eq(StoreStatisticsYear::getStoreId,dto.getStoreId());
                List<StoreStatisticsYear> storeStatisticsYears = storeStatisticsYearMapper.selectList(yearWrapper);
                moneyList = storeStatisticsYears.stream().map(StoreStatisticsYear::getMoney).toList();
            }
        }

        if (!moneyList.isEmpty()){
            for (BigDecimal money:moneyList) {
                storeMoneyAll = CommonUtil.bigDecimalAdd(storeMoneyAll,money);
            }
        }

        //查询店铺当前活动金额
        //待返利 待核销 已返利 不显示活动当前金额
        StoreActivity storeActivity = new StoreActivity();
        if (dto.getType() == null){
            LambdaQueryWrapper<StoreActivity> storeActivityWrapper = new LambdaQueryWrapper<>();
            storeActivityWrapper.select(StoreActivity::getMoney)
                    .eq(StoreActivity::getStoreId,dto.getStoreId())
                    .le(StoreActivity::getStartTime, TimeUtil.unixTime())
                    .ge(StoreActivity::getEndTime,TimeUtil.unixTime())
                    .eq(StoreActivity::getShelves,EShelves.onSale.getValue())
                    .eq(StoreActivity::getStatus,EStatus.on.getValue());
            storeActivity = storeActivityMapper.selectOne(storeActivityWrapper);
        }

        if (ObjectUtil.isNotEmpty(storeActivity)){
            vo.setActivityMoney(storeActivity.getMoney());
        }
        vo.setOrderNum(storeOrderListVoIPage.getTotal());
        vo.setStoreMoneyAll(storeMoneyAll);

        return vo;
    }



    @Override
    public StoreOrderVo getStoreByOrder(IdDto dto) {

        StoreOrderVo vo = new StoreOrderVo();

        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getId,dto.getId());
        Order order = getOnly(wrapper);

        if (ObjectUtil.isNotEmpty(order)){
            BeanUtil.copyProperties(order, vo);
            //查询店铺信息
            Store store = storeMapper.getNameInfo(vo.getStoreId());

            //查询下单用户信息
            User user = userMapper.getNicknameAndPhone(vo.getUserId());

            //查出订单商品信息
            List<OrderGoodsVo> goodsListDetailByOrderSn = orderGoodsService.getGoodsListDetailByOrderSn(vo.getOrderSn());
            //没有商品把店铺信息设置进去 前端需要展示
            if (goodsListDetailByOrderSn.isEmpty() && ObjectUtil.isNotEmpty(store)){
                OrderGoodsVo orderGoodsVo = new OrderGoodsVo();
                orderGoodsVo.setCover(AppConfigUtil.getUrlPrefix(store.getLogo(),EFileSize.logo.getValue()));
                orderGoodsVo.setGoodsName(store.getName());
                orderGoodsVo.setNum(1);
                orderGoodsVo.setPrice(order.getPrice());
                goodsListDetailByOrderSn.add(orderGoodsVo);
            }


            //查出订单地址
            LambdaQueryWrapper<OrderAddress> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.select(OrderAddress::getName, OrderAddress::getPhone, OrderAddress::getProvince, OrderAddress::getCity,
                    OrderAddress::getDistrict, OrderAddress::getStreet, OrderAddress::getAddress).eq(OrderAddress::getOrderSn, vo.getOrderSn());

            OrderAddress orderAddress = orderAddressService.getOnly(queryWrapper);
            OrderAddressVo addressVo = new OrderAddressVo();
            if (ObjectUtil.isNotEmpty(orderAddress)) {
                BeanUtils.copyProperties(orderAddress, addressVo);
            }

            //查询当前排名
            Integer nowSort = 0;
            if (vo.getIsScore() != EIsScore.finish.getValue() && vo.getVerify() != EVerify.rebate.getValue()){
                nowSort = storeActivityQueueMapper.getNowSort(vo.getStoreActivityId(), vo.getOrderSn(), EStoreActivityQueueStatus.wait.getValue());
            }

            //查询商家实际收款
            LambdaQueryWrapper<StoreSale> storeSaleWrapper = new LambdaQueryWrapper<>();
            storeSaleWrapper.select(StoreSale::getMoney)
                    .eq(StoreSale::getOrderId,vo.getId());
            StoreSale storeSale = storeSaleMapper.selectOne(storeSaleWrapper);

            if (ObjectUtil.isNotEmpty(store)){
                vo.setStoreName(store.getName());
                vo.setLogoUrl(AppConfigUtil.getUrlPrefix(store.getLogo(),EFileSize.logo.getValue()));
            }
            if (ObjectUtil.isNotEmpty(user)){
                vo.setNickname(user.getNickname());
                vo.setPhone(user.getPhone());
            }
            if (ObjectUtil.isNotEmpty(storeSale)){
                vo.setStoreMoney(storeSale.getMoney());
            }
            vo.setGoodsVos(goodsListDetailByOrderSn);
            vo.setAddressVo(addressVo);
            vo.setNowSort(nowSort);
        }
        return vo;
    }

    @Override
    public Long userIdByOrderId(Integer id) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Order::getUserId).eq(Order::getId,id);
        Order order = getOnly(wrapper);

        if (order == null){
            throw new GeneralException(HttpStatus.orderNoExist);
        }
        return order.getUserId();
    }


    @Override
    public boolean updateOrderStatus(Long orderSn, Long userId, Integer verifyStatus,Integer isScoreStatus) {
        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Order::getOrderSn,orderSn)
                .eq(Order::getUserId,userId)
                .eq(Order::getVerify,verifyStatus)
                .eq(Order::getIsScore,isScoreStatus)
                .set(Order::getStatus,EStatus.off.getValue());
        return update(wrapper);
    }




}
